package com.oa.tools.utils;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.SecureRandom;
import java.util.Random;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.binary.Base64;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;


public class SecurityUtil {
 
 /**
  * HmacSHA1解密
  */
 public static String encryptHmacSHA1(String content, String key){         
  try {             
   SecretKeySpec localSecretKeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "HmacSHA1");//加密密钥             
   Mac localMac = Mac.getInstance("HmacSHA1");             
   localMac.init(localSecretKeySpec);             
   localMac.update(content.getBytes("UTF-8"));//加密内容，             
   return Base64.encodeBase64String(localMac.doFinal());//获取加密结果并转 BASE64         
  } catch (Exception e) { 
   //e.printStackTrace();
   return null;         
  } 
 }  

 
 /***
  * MD5 加密
  */
 public static String MD5(String str) {
  if (str == null)
   return null;
  try {
   MessageDigest md5 = MessageDigest.getInstance("MD5");
   md5.update(str.getBytes("UTF-8"));
   byte[] digest = md5.digest();
   StringBuffer hexString = new StringBuffer();
   String strTemp;
   for (int i = 0; i < digest.length; i++) {
    strTemp = Integer.toHexString((digest[i] & 0x000000FF) | 0xFFFFFF00).substring(6);
    hexString.append(strTemp);
   }
   return hexString.toString();
  } catch (Exception e) {
   e.printStackTrace();
  }
  return str;
 }
 
 public static String MD5(byte[] data) {
  try {
   MessageDigest md5 = MessageDigest.getInstance("MD5");
   md5.update(data);
   byte[] digest = md5.digest();
   StringBuffer hexString = new StringBuffer();
   String strTemp;
   for (int i = 0; i < digest.length; i++) {
    strTemp = Integer.toHexString((digest[i] & 0x000000FF) | 0xFFFFFF00).substring(6);
    hexString.append(strTemp);
   }
   return hexString.toString();
  } catch (Exception e) {
   e.printStackTrace();
  }
  return new String(data);
 }

 // ==Base64加解密==================================================================
 /**
  * Base64加密
  */
 public static String Base64Encode(String str) throws UnsupportedEncodingException {
  return new BASE64Encoder().encode(str.getBytes("UTF-8"));
 }

 /**
  * 解密
  */
 public static String Base64Decode(String str) throws UnsupportedEncodingException, IOException {
//  str = str.replaceAll(" ", "+");
  return new String(new BASE64Decoder().decodeBuffer(str), "UTF-8");
 }

 // ==Aes加解密==================================================================
 /**
  * aes解密-128位
  */
 public static String AesDecrypt(String encryptContent, String password) {
  try {
   KeyGenerator keyGen = KeyGenerator.getInstance("AES");
   SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
   secureRandom.setSeed(password.getBytes());
   keyGen.init(128, secureRandom);
   SecretKey secretKey = keyGen.generateKey();
   byte[] enCodeFormat = secretKey.getEncoded();
   SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
   Cipher cipher = Cipher.getInstance("AES");
   cipher.init(Cipher.DECRYPT_MODE, key);
   return new String(cipher.doFinal(hex2Bytes(encryptContent)));
  } catch (Exception e) {
   e.printStackTrace();
   return null;
  }

 }

 /**
  * aes加密-128位
  */
 public static String AesEncrypt(String content, String password) {
  try {
   KeyGenerator keyGen = KeyGenerator.getInstance("AES");
   SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
   secureRandom.setSeed(password.getBytes());
   keyGen.init(128, secureRandom);
   SecretKey secretKey = keyGen.generateKey();
   byte[] enCodeFormat = secretKey.getEncoded();
   SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
   Cipher cipher = Cipher.getInstance("AES");
   cipher.init(Cipher.ENCRYPT_MODE, key);
   return byte2Hex(cipher.doFinal(content.getBytes("UTF-8")));
  } catch (Exception e) {
   e.printStackTrace();
   return null;
  }
 }

 /**
  * 将byte[] 转换成字符串
  */
 public static String byte2Hex(byte[] srcBytes) {
  StringBuilder hexRetSB = new StringBuilder();
  for (byte b : srcBytes) {
   String hexString = Integer.toHexString(0x00ff & b);
   hexRetSB.append(hexString.length() == 1 ? 0 : "").append(hexString);
  }
  return hexRetSB.toString();
 }

 /**
  * 将16进制字符串转为转换成字符串
  */
 public static byte[] hex2Bytes(String source) {
  byte[] sourceBytes = new byte[source.length() / 2];
  for (int i = 0; i < sourceBytes.length; i++) {
   sourceBytes[i] = (byte) Integer.parseInt(source.substring(i * 2, i * 2 + 2), 16);
  }
  return sourceBytes;
 }

 /**
  * DES加密
  */
 public static String desEncrypt(String source, String desKey) throws Exception {
  try {
   // 从原始密匙数据创建DESKeySpec对象
   SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
   SecretKey securekey = keyFactory.generateSecret(new DESKeySpec(desKey.getBytes()));
   // Cipher对象实际完成加密操作
   Cipher cipher = Cipher.getInstance("DES");
   // 用密匙初始化Cipher对象
   cipher.init(Cipher.ENCRYPT_MODE, securekey);
   // 现在，获取数据并加密
   byte[] destBytes = cipher.doFinal(source.getBytes());
   StringBuilder hexRetSB = new StringBuilder();
   for (byte b : destBytes) {
    String hexString = Integer.toHexString(0x00ff & b);
    hexRetSB.append(hexString.length() == 1 ? 0 : "").append(hexString);
   }
   return hexRetSB.toString();
  } catch (Exception e) {
   throw new Exception("DES加密发生错误", e);
  }
 }

 /**
  * DES解密
  */
 public static String desDecrypt(String source, String desKey) throws Exception {
  // 解密数据
  byte[] sourceBytes = new byte[source.length() / 2];
  for (int i = 0; i < sourceBytes.length; i++) {
   sourceBytes[i] = (byte) Integer.parseInt(source.substring(i * 2, i * 2 + 2), 16);
  }
  try {
   SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
   SecretKey securekey = keyFactory.generateSecret(new DESKeySpec(desKey.getBytes()));
   Cipher cipher = Cipher.getInstance("DES");
   // 用密匙初始化Cipher对象
   cipher.init(Cipher.DECRYPT_MODE, securekey);
   // 现在，获取数据并解密
   byte[] destBytes = cipher.doFinal(sourceBytes);
   return new String(destBytes);
  } catch (Exception e) {
   throw new Exception("DES解密发生错误", e);
  }
 }

 /**
  * 3DES加密
  */
 public static byte[] threeDesEncrypt(byte[] src, byte[] keybyte) throws Exception {
  try {
   // 生成密钥
   byte[] key = new byte[24];
   if (keybyte.length < key.length) {
    System.arraycopy(keybyte, 0, key, 0, keybyte.length);
   } else {
    System.arraycopy(keybyte, 0, key, 0, key.length);
   }
   SecretKey deskey = new SecretKeySpec(key, "DESede");
   // 加密
   Cipher c1 = Cipher.getInstance("DESede/ECB/PKCS5Padding");
   c1.init(Cipher.ENCRYPT_MODE, deskey);
   return c1.doFinal(src);
  } catch (Exception e) {
   throw new Exception("3DES加密发生错误", e);
  }
 }

 /**
  * 3DES解密
  */
 public static byte[] threeDesDecrypt(byte[] src, byte[] keybyte) throws Exception {
  try {
   // 生成密钥
   byte[] key = new byte[24];
   if (keybyte.length < key.length) {
    System.arraycopy(keybyte, 0, key, 0, keybyte.length);
   } else {
    System.arraycopy(keybyte, 0, key, 0, key.length);
   }
   SecretKey deskey = new SecretKeySpec(key, "DESede");
   // 解密
   Cipher c1 = Cipher.getInstance("DESede/ECB/PKCS5Padding");
   c1.init(Cipher.DECRYPT_MODE, deskey);
   return c1.doFinal(src);
  } catch (Exception e) {
   throw new Exception("3DES解密发生错误", e);
  }
 }

 /**
  * 3DES加密
  */
 public static String threeDesEncrypt(String src, String key) throws Exception {
  return byte2Hex(threeDesEncrypt(src.getBytes(), key.getBytes()));
 }

 /**
  * 3DES加密
  */
 public static String threeDesDecrypt(String src, String key) throws Exception {
  return new String(threeDesDecrypt(hex2Bytes(src), key.getBytes()));
 }

 /*public static void main(String[] args) throws Exception {
  String str = "数据加密的基本过程就是对原来为明文的文件或数据按某种算法进行处理，使其成为不可读的一段代码，通常称为“密文”，" 
    + "使其只能在输入相应的密钥之后才能显示出本来内容，通过这样的途径来达到保护数据不被非法人窃取、阅读的目的。 " 
    + "该过程的逆过程为解密，即将该编码信息转化为其原来数据的过程。";
  str+=str;str+=str;str+=str;
  String PWD = "SecurityUtil.PWD";
  System.out.println("原文:[" + str.length() + "]" + str);
  System.out.println("==MD5===============");
  System.out.println(MD5(str));
  System.out.println("==Base64============");
  String strBase64 = Base64Encode(str);
  System.out.println("加密:[" + strBase64.length() + "]" + strBase64);
  System.out.println("解密:" + Base64Decode(strBase64));
  System.out.println("==Aes============");
  String strAes = AesEncrypt(str, PWD);
  System.out.println("加密:[" + strAes.length() + "]" + strAes);
  System.out.println("解密:" + AesDecrypt(strAes, PWD));
  System.out.println("==Des==============");
  String strDes = desEncrypt(str, PWD);
  System.out.println("加密:[" + strDes.length() + "]" + strDes);
  System.out.println("解密:" + desDecrypt(strDes, PWD));
  System.out.println("==3Des==============");
  String str3Des = threeDesEncrypt(str, PWD);
  System.out.println("加密:[" + str3Des.length() + "]" + str3Des);
  System.out.println("解密:" + threeDesDecrypt(str3Des, PWD));
  
  //==========================================
  
  long t1=System.currentTimeMillis();   
  for (int i = 0; i < 10000; i++) 
   MD5(str);
  System.out.println("\nMD5:"+(System.currentTimeMillis()-t1));
  t1=System.currentTimeMillis();   
  for (int i = 0; i < 10000; i++) 
   Base64Encode(str);
  System.out.println("Base64:"+(System.currentTimeMillis()-t1));
  t1=System.currentTimeMillis();   
  for (int i = 0; i < 10000; i++) 
   AesEncrypt(str, PWD);
  System.out.println("Aes:"+(System.currentTimeMillis()-t1));
  t1=System.currentTimeMillis();   
  for (int i = 0; i < 10000; i++) 
   desEncrypt(str, PWD);
  System.out.println("Des:"+(System.currentTimeMillis()-t1));
  t1=System.currentTimeMillis();   
  for (int i = 0; i < 10000; i++) 
   threeDesEncrypt(str, PWD);
  System.out.println("3Des:"+(System.currentTimeMillis()-t1));
  //=======================================
  t1=System.currentTimeMillis();   
  for (int i = 0; i < 10000; i++) 
   Base64Decode(strBase64);
  System.out.println("\nBase64:"+(System.currentTimeMillis()-t1));
  t1=System.currentTimeMillis();   
  for (int i = 0; i < 10000; i++) 
   AesDecrypt(strAes, PWD);
  System.out.println("Aes:"+(System.currentTimeMillis()-t1));
  t1=System.currentTimeMillis();   
  for (int i = 0; i < 10000; i++) 
   desDecrypt(strDes, PWD);
  System.out.println("Des:"+(System.currentTimeMillis()-t1));
  t1=System.currentTimeMillis();   
  for (int i = 0; i < 10000; i++) 
   threeDesDecrypt(str3Des, PWD);
  System.out.println("3Des:"+(System.currentTimeMillis()-t1));

  
 }*/
 
   //生成随机数字和字母,  
    public static String getStringRandom(int length) {  

        String val = "";  
        Random random = new Random();        
        //length为几位密码 
        for(int i = 0; i < length; i++) {          
            String charOrNum = random.nextInt(2) % 2 == 0 ? "char" : "num";  
            //输出字母还是数字  
            if( "char".equalsIgnoreCase(charOrNum) ) {  
                //输出是大写字母还是小写字母  
                int temp = random.nextInt(2) % 2 == 0 ? 65 : 97;  
                val += (char)(random.nextInt(26) + temp);  
            } else if( "num".equalsIgnoreCase(charOrNum) ) {  
                val += String.valueOf(random.nextInt(10));  
            }  
        }  
        return val;  
    }  
    
    

     //生产的密码包括位数 
    public static void  main(String[] args) throws Exception {  
   /*  String path ="C:\\Users\\dell\\Desktop\\20180725\\T20180725032452__Result__FB__Output.zip" ; 
     File file =new File(path);
     byte[] data = new byte[(int) file.length()];
     FileInputStream fis = new FileInputStream(path);
     fis.read(data);
     System.out.println("data md5 :"+MD5(data));
     fis.close();
     
     String content = FileUtil.readTxt(path,"utf-8");
     System.out.println(content);
       
       System.out.println(MD5(content));*/
    	
    	String appSecret="dtH@1NusTcx5OkC4YBqH";
    	String signSrc = "appKey=appadmsTWWB975648&employeeId=db94ef87eff84ff08d5842e819d1af22&entryDate=2015-10-11&fields={\"工作邮箱\":\"\":\"sushaolei@fengbangleasing.com\"}&h\"}&hireType=0&mobile=18911367884&name=缑秀华&timestamp=1534241995056";
    
    	System.out.println("https://api.xinrenxinshi.com/v2/employee/getFieldIds?"+signSrc+"&sign="+SecurityUtil.encryptHmacSHA1(signSrc, appSecret));
    	
    	//https://api.xinrenxinshi.com/v2/employee/getFieldIds?appKey=appadmsTWWB975648&timestamp=1534233944355&sign=F3CqeL8rOHWwF0Ecu+Hx8eHhN7M=

    }  

}
